package com.uinnova.product.eam.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.binary.core.exception.BinaryException;
import com.binary.core.util.BinaryUtils;
import com.binary.framework.exception.ServiceException;
import com.binary.framework.web.RemoteResult;
import com.binary.jdbc.Page;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.uinnova.product.eam.base.util.EamUtil;
import com.uinnova.product.eam.comm.model.es.AssetAttrDataScreen;
import com.uinnova.product.eam.comm.model.es.EamCategory;
import com.uinnova.product.eam.comm.model.es.EamMultiModelHierarchy;
import com.uinnova.product.eam.model.*;
import com.uinnova.product.eam.model.bm.VcCiQ;
import com.uinnova.product.eam.model.bm.VcCiSearchPage;
import com.uinnova.product.eam.model.dto.DiagramSelectParamDto;
import com.uinnova.product.eam.model.dto.EamHierarchyDto;
import com.uinnova.product.eam.model.dto.ElementDto;
import com.uinnova.product.eam.model.dto.LaneDragCiDto;
import com.uinnova.product.eam.model.enums.ArtifactType;
import com.uinnova.product.eam.model.vo.*;
import com.uinnova.product.eam.service.*;
import com.uinnova.product.eam.service.es.IamsCIDesignNonComplianceDao;
import com.uinnova.product.eam.service.es.IamsCIPrivateNonComplianceDao;
import com.uinnova.product.eam.service.es.IamsESCIDesignSvc;
import com.uinnova.product.eam.service.es.IamsESCIPrivateSvc;
import com.uinnova.product.vmdb.comm.model.ci.CCcCi;
import com.uinnova.product.vmdb.comm.model.ci.CcCi;
import com.uinnova.product.vmdb.comm.model.ci.CcCiAttrDef;
import com.uinnova.product.vmdb.comm.model.ci.CcCiClass;
import com.uinnova.product.vmdb.provider.ci.bean.CcCiClassInfo;
import com.uinnova.product.vmdb.provider.ci.bean.CcCiInfo;
import com.uinnova.product.vmdb.provider.ci.bean.CiClassSaveInfo;
import com.uinnova.product.vmdb.provider.ci.bean.CiGroupPage;
import com.uinnova.product.vmdb.provider.search.bean.CcCiClassObj;
import com.uinnova.product.vmdb.provider.search.bean.CcCiObj;
import com.uinnova.product.vmdb.provider.search.bean.CcCiSearchPage;
import com.uinnova.project.api.diagram.v2.client.ESDiagramApiClient;
import com.uinnova.project.base.diagram.comm.model.ESDiagram;
import com.uinnova.project.base.diagram.comm.model.ESDiagramDTO;
import com.uinnova.project.db.eam.ESDiagramDao;
import com.uinnova.project.db.eam.ESDiagramNodeDao;
import com.uinnova.project.model.diagram.DiagramRelationInfo;
import com.uino.api.client.cmdb.ICIApiSvc;
import com.uino.api.client.cmdb.ICIClassApiSvc;
import com.uino.bean.cmdb.base.*;
import com.uino.bean.cmdb.business.*;
import com.uino.bean.cmdb.query.*;
import com.uino.bean.permission.base.SysUser;
import com.uino.dao.BaseConst;
import com.uino.dao.cmdb.CiClassProDropSourceDefHelper;
import com.uino.dao.cmdb.ESCIClassSvc;
import com.uino.service.cmdb.microservice.ICIClassSvc;
import com.uino.service.cmdb.microservice.ICISvc;
import com.uino.service.sys.microservice.IDictionarySvc;
import com.uino.util.sys.LibTypeUtil;
import com.uino.util.sys.SysUtil;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.sort.SortBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

@Service
public class IamsCISwitchSvc implements ICISwitchSvc {

    @Autowired
    private ICIApiSvc iciApiSvc;

    @Autowired
    private ICIClassApiSvc classSvc;

    @Autowired
    private IamsCIPrivateSvc iamsCiPrivateSvc;

    @Autowired
    private IamsCIDesignSvc iamsCiDesignSvc;

    @Value("${http.resource.space}")
    private String urlPrefix;

    @Autowired
    private ESDiagramApiClient diagramApiClient;

    @Autowired
    private IEamArtifactColumnSvc eamArtifactColumnSvc;

    @Autowired
    private IDictionarySvc dictSvc;

    @Autowired
    private ICISwitchSvc iciSwitchSvc;

    @Resource
    private IEamCIClassApiSvc ciClassApiSvc;

    @Resource
    private BmHierarchySvcImpl hierarchySvc;
    @Resource
    private EamCategorySvc categorySvc;
    @Resource
    private IamsCIRltSwitchSvc rltSwitchSvc;

    @Resource
    private IBmMultiModelHierarchySvc modelHierarchySvc;

    @Autowired
    private IamsESCIDesignSvc iamsESCIDesignSvc;

    @Autowired
    private IamsESCIPrivateSvc iamsESCIPrivateSvc;

    @Autowired
    private ESDiagramDao esDiagramDao;

    @Autowired
    private ESDiagramNodeDao esDiagramNodeDao;

    @Autowired
    private IamsCIPrivateNonComplianceDao iamsCIPrivateNonComplianceDao;

    @Autowired
    private IamsCIDesignNonComplianceDao iamsCIDesignNonComplianceDao;

    @Resource
    private IEamCiSvc eamCiSvc;

    @Resource
    private ICIClassSvc esClsSvc;

    @Resource
    ESCIClassSvc esciClassSvc;

    @Resource
    AssetAttrDataScreenSvc assetAttrDataScreenSvc;


    private static int DATA_DICT = 8;    // 属性 proType 为数据字典

    private static int REL_ATTR = 11;    // 属性 proType 为关联属性

    @Override
    public ICIApiSvc getCiApiSvc() {
        return iciApiSvc;
    }

    @Override
    public CcCiInfo getCiInfoById(Long id, LibType libType) {
        if (LibType.BASELINE.equals(libType)) {
            return iciApiSvc.getCiInfoById(id);
        } else {
            return getCiSvc(libType).getCiInfoById(id);
        }
    }

    @Override
    public List<ESCIInfo> getCiByCodes(List<String> ciCodes, String ownerCode, LibType libType) {
        if(CollectionUtils.isEmpty(ciCodes)){
            return Collections.emptyList();
        }
        ESCISearchBean bean = new ESCISearchBean();
        bean.setCiCodes(ciCodes);
        if (LibType.PRIVATE.equals(libType)) {
            if (BinaryUtils.isEmpty(ownerCode)) {
                return Collections.emptyList();
            } else {
                bean.setOwnerCode(ownerCode);
            }
        }
        bean.setPageNum(1);
        bean.setPageSize(10000);
        bean.setDomainId(SysUtil.getCurrentUserInfo().getDomainId());
        Page<ESCIInfo> page = searchESCIByBean(bean, libType);
        return BinaryUtils.isEmpty(page.getData()) ? Collections.emptyList() : page.getData();
    }

    @Override
    public List<ESCIInfo> getCiByClassIds(List<Long> ciCodes, String ownerCode, LibType libType) {
        ESCISearchBean bean = new ESCISearchBean();
        bean.setClassIds(ciCodes);
        if (LibType.PRIVATE.equals(libType)) {
            if (BinaryUtils.isEmpty(ownerCode)) {
                return Collections.emptyList();
            } else {
                bean.setOwnerCode(ownerCode);
            }
        }
        bean.setPageNum(1);
        bean.setPageSize(10000);
        bean.setDomainId(SysUtil.getCurrentUserInfo().getDomainId());
        Page<ESCIInfo> page = searchESCIByBean(bean, libType);
        return BinaryUtils.isEmpty(page.getData()) ? Collections.emptyList() : page.getData();
    }

    @Override
    public List<ESCIInfo> getCiByPrimaryKeys(Collection<String> primaryKeys, String ownerCode, LibType libType) {
        ESCISearchBean bean = new ESCISearchBean();
        bean.setCiPrimaryKeys(primaryKeys);
        if (LibType.PRIVATE.equals(libType)) {
            if (BinaryUtils.isEmpty(ownerCode)) {
                return Collections.emptyList();
            } else {
                bean.setOwnerCode(ownerCode);
            }
        }
        bean.setPageNum(1);
        bean.setPageSize(10000);
        bean.setDomainId(SysUtil.getCurrentUserInfo().getDomainId());
        Page<ESCIInfo> page = searchESCIByBean(bean, libType);
        return BinaryUtils.isEmpty(page.getData()) ? Collections.emptyList() : page.getData();
    }

    @Override
    public CiGroupPage queryPageByIndex(Integer pageNum, Integer pageSize, CiQueryCdtExtend cdt, Boolean hasClass, LibType libType) {
        if (LibType.BASELINE.equals(libType)) {
            return iciApiSvc.queryPageByIndex(pageNum, pageSize, cdt, hasClass);
        } else {
            return getCiSvc(libType).queryPageByIndex(BaseConst.DEFAULT_DOMAIN_ID, pageNum, pageSize, cdt, hasClass);
        }
    }

    @Override
    public CiGroupPage queryPageBySearchBean(ESCISearchBean bean, Boolean hasClass, LibType libType) {
        if (LibType.BASELINE.equals(libType)) {
            return iciApiSvc.queryPageBySearchBean(bean, hasClass);
        } else {
            return getCiSvc(libType).queryPageBySearchBean(bean, hasClass);
        }
    }

    @Override
    public List<CcCi> queryCiList(Long domainId, CCcCi cdt, String orders, Boolean isAsc, LibType libType) {
        if (LibType.BASELINE.equals(libType)) {
            return iciApiSvc.queryCiList(domainId, cdt, orders, isAsc);
        } else {
            return getCiSvc(libType).queryCiList(domainId, cdt, orders, isAsc);
        }
    }

    @Override
    public List<ESCIInfo> queryESCIInfoList(Long domainId, CCcCi cdt, String orders, Boolean isAsc, LibType libType) {
        if (LibType.BASELINE.equals(libType)) {
            return iciApiSvc.queryESCIInfoList(domainId, cdt, orders, isAsc);
        } else {
            return getCiSvc(libType).queryESCIInfoList(domainId, cdt, orders, isAsc);
        }
    }

    @Override
    public List<CcCiInfo> queryCiInfoList(Long domainId, CCcCi cdt, String orders, Boolean isAsc, Boolean hasClass, LibType libType) {
        List<CcCiInfo> ccCiInfos;
        if (LibType.BASELINE.equals(libType)) {
            ccCiInfos = iciApiSvc.queryCiInfoList(domainId, cdt, orders, isAsc, hasClass);
        } else {
            ccCiInfos = getCiSvc(libType).queryCiInfoList(domainId, cdt, orders, isAsc, hasClass);
        }

        if (ccCiInfos != null && ccCiInfos.size() > 0) {
            spliceIconAddress(ccCiInfos);
        }
        return ccCiInfos;
    }

    /**
     * 拼接地址
     *
     * @param ccCiInfos {@link CcCiInfo} 的集合
     */
    private void spliceIconAddress(List<CcCiInfo> ccCiInfos) {
        for (CcCiInfo item : ccCiInfos) {
            CcCiClass ciClass = item.getCiClass();
            if (ciClass != null) {
                String icon = ciClass.getIcon();
                if (!BinaryUtils.isEmpty(icon) && !icon.startsWith(urlPrefix)) {
                    ciClass.setIcon(urlPrefix + icon);
                }
            }
        }
    }

    @Override
    public Page<CcCiInfo> queryCiInfoPage(Long domainId, Integer pageNum, Integer pageSize, CCcCi cdt,
                                          String orders, Boolean isAsc, Boolean hasClass, LibType libType) {
        if (LibType.BASELINE.equals(libType)) {
            return iciApiSvc.queryCiInfoPage(domainId, pageNum, pageSize, cdt, orders, isAsc, hasClass);
        } else {
            return getCiSvc(libType).queryCiInfoPage(domainId, pageNum, pageSize, cdt, orders, isAsc, hasClass);
        }
    }

    @Override
    public CcCiSearchPage searchCIByCdt(int pageNum, int pageSize, CCcCi bean, LibType libType) {
        if (LibType.BASELINE.equals(libType)) {
            return iciApiSvc.searchCIByCdt(pageNum, pageSize, bean);
        } else {
            return getCiSvc(libType).searchCIByCdt(pageNum, pageSize, bean);
        }
    }

    @Override
    public Page<ESCIInfo> searchESCIByBean(ESCISearchBean bean, LibType libType) {
        if (LibType.BASELINE.equals(libType)) {
            return iciApiSvc.searchESCIByBean(bean);
        } else {
            return getCiSvc(libType).searchESCIByBean(bean);
        }
    }

    @Override
    public CcCiSearchPage searchCIByBean(ESCISearchBean bean, LibType libType) {
        if (LibType.BASELINE.equals(libType)) {
            return iciApiSvc.searchCIByBean(bean);
        } else {
            return getCiSvc(libType).searchCIByBean(bean);
        }
    }

    @Override
    public Long saveOrUpdateCI(CcCiInfo ciInfo, LibType libType) {
        if (LibType.BASELINE.equals(libType)) {
            return iciApiSvc.saveOrUpdateCI(ciInfo);
        } else {
            return getCiSvc(libType).saveOrUpdate(ciInfo);
        }
    }

    @Override
    public Long saveOrUpdateCI(CcCiInfo ciInfo, LibType libType, SaveType saveType) {
        if (LibType.BASELINE.equals(libType)) {
            return iciApiSvc.saveOrUpdateCI(ciInfo, saveType);
        } else {
            return getCiSvc(libType).saveOrUpdate(ciInfo, saveType);
        }
    }

    @Override
    public Long saveOrUpdateExtra(CcCiInfo ciInfo, LibType libType) {
        // 临时处理私有库localVersion字段归0
        if (LibType.BASELINE.equals(libType)) {
            return iciApiSvc.saveOrUpdateCIExtra(ciInfo);
        } else {
            return getCiSvc(libType).saveOrUpdateExtra(ciInfo);
        }
    }

    @Override
    public Map<String, ? extends SaveBatchCIContext> saveOrUpdateBatchCI(List<ESCIInfo> ciList, List<Long> classIds, String ownerCode, String loginCode, LibType libType) {
        if (LibType.BASELINE.equals(libType)) {
            return iciApiSvc.saveOrUpdateBatchCI(ciList, classIds, ownerCode, loginCode);
        } else {
            return getCiSvc(libType).saveOrUpdateBatchCI(ciList, classIds, ownerCode, loginCode);
        }
    }

    @Override
    public Map<String, ? extends SaveBatchCIContext> saveOrUpdateBatchCIWithoutCIOpLog(List<ESCIInfo> ciList, List<Long> classIds, String ownerCode, String loginCode, LibType libType) {
        if (LibType.BASELINE.equals(libType)) {
            return iciApiSvc.saveOrUpdateBatchCIWithoutCIOpLog(ciList, classIds, ownerCode, loginCode);
        } else {
            return getCiSvc(libType).saveOrUpdateBatchCIWithoutCIOpLog(ciList, classIds, ownerCode, loginCode);
        }
    }

    @Override
    public Integer updateESCIInfoBatch(List<ESCIInfo> esCiInfoList, LibType libType) {
        if (LibType.BASELINE.equals(libType)) {
            return iciApiSvc.updateESCIInfoBatch(esCiInfoList);
        } else {
            return getCiSvc(libType).updateESCIInfoBatch(esCiInfoList);
        }
    }

    @Override
    public Integer removeById(Long id, Long sourceId, LibType libType) {
        if (LibType.BASELINE.equals(libType)) {
            return iciApiSvc.removeById(id, sourceId);
        } else {
            return getCiSvc(libType).deleteById(id, sourceId);
        }
    }

    @Override
    public Integer removeByIds(List<Long> ciIds, Long sourceId, LibType libType) {
        if (LibType.BASELINE.equals(libType)) {
            return iciApiSvc.removeByIds(ciIds, sourceId);
        } else {
            return getCiSvc(libType).removeByIds(ciIds, sourceId);
        }
    }

    @Override
    public Integer removeByClassId(Long classId, Long sourceId, LibType libType) {
        if (LibType.BASELINE.equals(libType)) {
            return iciApiSvc.removeByClassId(classId, sourceId);
        } else {
            return getCiSvc(libType).removeByClassId(classId, sourceId);
        }
    }

    @Override
    public ImportSheetMessage saveOrUpdateCiBatch(Long domainId, CiClassSaveInfo saveInfo, LibType libType) {
        if (LibType.BASELINE.equals(libType)) {
            return iciApiSvc.saveOrUpdateCiBatch(domainId, saveInfo);
        } else {
            return getCiSvc(libType).saveOrUpdateCiBath(domainId, saveInfo);
        }
    }

    @Override
    public ResponseEntity<byte[]> exportCiOrClass(ExportCiDto exportDto, LibType libType) {
        if (LibType.BASELINE.equals(libType)) {
            return iciApiSvc.exportCiOrClass(exportDto);
        } else {
            return getCiSvc(libType).exportCiOrClass(exportDto);
        }
    }

    @Override
    public ImportResultMessage importCiByCiClsIds(MultipartFile file, Long classId, LibType libType) {
        if (LibType.BASELINE.equals(libType)) {
            return iciApiSvc.importCiByCiClsIds(file, classId);
        } else {
            return getCiSvc(libType).importCiByCiClsIds(file, classId);
        }
    }

    @Override
    public ImportExcelMessage importCiExcel(MultipartFile file, LibType libType) {
        if (LibType.BASELINE.equals(libType)) {
            return iciApiSvc.importCiExcel(file);
        } else {
            return getCiSvc(libType).importCiExcel(file);
        }
    }

    @Override
    public ImportResultMessage importCiByClassBatch(CiExcelInfoDto excelInfoDto, LibType libType) {
        if (LibType.BASELINE.equals(libType)) {
            return iciApiSvc.importCiByClassBatch(excelInfoDto);
        } else {
            Long domainId = SysUtil.getCurrentUserInfo().getDomainId();
            return getCiSvc(libType).importCiByClassBatch(domainId, excelInfoDto, false);
        }
    }

    @Override
    public Map<Long, Long> countCiNumGroupClsByQuery(ESCISearchBean bean, LibType libType) {
        if (LibType.BASELINE.equals(libType)) {
            return iciApiSvc.countCiNumGroupClsByQuery(bean);
        } else {
            return getCiSvc(libType).countCiNumGroupClsByQuery(bean);
        }
    }

    @Override
    public Page<String> getAttrValuesBySearchBean(ESAttrAggBean searchBean, LibType libType) {
        if (LibType.BASELINE.equals(libType)) {
            return iciApiSvc.getAttrValuesBySearchBean(searchBean);
        } else {
            return getCiSvc(libType).getAttrValuesBySearchBean(searchBean);
        }
    }

    @Override
    public Page<ESCIInfo> getESCIInfoPageByQuery(Long domainId, int pageNum, int pageSize, QueryBuilder query, List<SortBuilder<?>> sorts, Boolean isHighLight, LibType libType) {
        if (LibType.BASELINE.equals(libType)) {
            return iciApiSvc.getESCIInfoPageByQuery(pageNum, pageSize, query, sorts, isHighLight);
        } else {
            return getCiSvc(libType).getESCIInfoPageByQuery(domainId, pageNum, pageSize, query, sorts, isHighLight);
        }
    }

    @Override
    public Map<String, Long> getCICodeMaxVersion(List<String> ciCodes, LibType libType) {
        if (LibType.BASELINE.equals(libType)) {
            return new HashMap<>();
        } else if (LibType.PRIVATE.equals(libType)) {
            throw new BinaryException("私有库暂不支持");
        } else {
            return iamsCiDesignSvc.getCICodeMaxVersion(ciCodes);
        }
    }

    @Override
    public Map<String, Long> getMaxVersionByPrimaryKey(List<String> primaryKeys, LibType libType) {
        if (LibType.BASELINE.equals(libType)) {
            return new HashMap<>();
        } else if (LibType.PRIVATE.equals(libType)) {
            throw new BinaryException("私有库暂不支持");
        } else {
            return iamsCiDesignSvc.getMaxVersionByPrimaryKey(primaryKeys);
        }
    }

    @Override
    public List<ClassNodeInfo> getClassTree(Boolean display, LibType libType) {
        List<ClassNodeInfo> classTree = classSvc.getClassTree();
        Map<String, Long> map;
        if (LibType.BASELINE.equals(libType)) {
            map = iciApiSvc.queryCiCountByClassId();
        } else {
            map = getCiSvc(libType).queryCiCountByClassId();
        }
        for (ClassNodeInfo nodeInfo : classTree) {
            for (ClassNodeInfo child : nodeInfo.getChildren()) {
                child.setCount(map.get(String.valueOf(child.getId())));
            }
        }
        if(display){
            List<Long> displayDomainId = eamCiSvc.getDisplayDomain();
            classTree = classTree.stream().filter(each -> !displayDomainId.contains(each.getId())).collect(Collectors.toList());
        }
        return classTree;
    }

    /**
     * 获取私有库或设计库的Svc
     *
     * @param libType (PRIVATE 私有库, DESIGN 设计库）
     * @return ICISvc
     */
    @Override
    public ICISvc getCiSvc(LibType libType) {
        if (LibType.PRIVATE.equals(libType)) {
            return iamsCiPrivateSvc;
        } else {
            return iamsCiDesignSvc;
        }
    }

    @Override
    public Integer handleCiExist(List<Long> ids, LibType libType, String ownerCode) {
        if (Objects.equals(libType, LibType.DESIGN)) {
            ESCISearchBean bean = new ESCISearchBean();
            CCcCi cdt = new CCcCi();
            cdt.setIds(ids.toArray(new Long[0]));
            bean.setCdt(cdt);
            Page<ESCIInfo> designCiPage = iamsCiDesignSvc.searchESCIByBean(bean);
            List<ESCIInfo> designList = designCiPage.getData();
            if (CollectionUtils.isEmpty(designList)) {
                throw new ServiceException("获取设计库数据失败!");
            }
            return checkPrivateExistStatus(designList, ownerCode);
        } else if (Objects.equals(libType, LibType.PRIVATE)) {
            ESCISearchBean bean = new ESCISearchBean();
            CCcCi cdt = new CCcCi();
            cdt.setIds(ids.toArray(new Long[0]));
            bean.setCdt(cdt);
            bean.setOwnerCode(SysUtil.getCurrentUserInfo().getLoginCode());
            Page<ESCIInfo> cooperCiPage = iamsCiPrivateSvc.searchESCIByBean(bean);
            List<ESCIInfo> cooperCiList = cooperCiPage.getData();
            if (CollectionUtils.isEmpty(cooperCiList)) {
                throw new ServiceException("获取私有库数据失败!");
            }
            return checkPrivateExistStatus(cooperCiList, ownerCode);
        } else {
            throw new ServiceException("数据库分类标识参数错误!");
        }
    }

    @Override
    public Integer removeByOwnerCodeAndClassId(LibType libType, Long classId, String ownerCode) {
        if (LibType.BASELINE.equals(libType)) {
            return iciApiSvc.removeByOwnerCodeAndClassId(classId, ownerCode);
        } else {
            return getCiSvc(libType).removeByOwnerCodeAndClassId(classId, ownerCode);
        }
    }


    @Override
    public List<SysUser> findCiSwitchUserList(ESCISearchBean bean, Boolean hasClass) {
        return iamsCiPrivateSvc.findCiSwitchUserList(bean, hasClass);
    }

    @Override
    public List<VcCiSearchPage> queryPageByAllIndex(Integer pageNum, Integer pageSize, CiQueryCdtExtend cdt, String orders, VcCiQ[] vcCiQS) {
        Long domainId = SysUtil.getCurrentUserInfo().getDomainId();
        List<VcCiSearchPage> ciSearchPages = new ArrayList<>();
        String[] words = cdt.getWords();

        if (!ArrayUtils.isEmpty(words)) {
            for (String word : words) {
                VcCiSearchPage ciDataByWord = getCiDataByWord(pageNum, pageSize, cdt, word);
                ciSearchPages.add(ciDataByWord);
            }
        } else {
            CCcCi ciCdt = new CCcCi();
            ciCdt.setDomainId(domainId);

            List<Long> classIds = new ArrayList<>();
            CiQueryCdtExtend cdtInfo = new CiQueryCdtExtend();
            cdtInfo.setViewType(cdt.getProductTypeId());
            cdtInfo.setOwnerCode(cdt.getOwnerCode());
            cdtInfo.setCardId(null);
            List<VcCiClassInfoDto> vcCiClassInfoDtos = eamCiSvc.queryCiCountByClass(cdtInfo, cdt.getLibType());
            if (!CollectionUtils.isEmpty(vcCiClassInfoDtos)) {
                classIds = vcCiClassInfoDtos.stream().map(ciClass -> ciClass.getCiClass().getId()).collect(Collectors.toList());
            } else {
                if (BinaryUtils.isEmpty(cdt.getClassId()) && cdt.getProductTypeId() != null) {
                    ElementDto elementDto = new ElementDto();
                    elementDto.setArtifactId(Long.valueOf(cdt.getProductTypeId()));
                    elementDto.setType(ArtifactType.ASSET_TYPE.val());
                    List<EamArtifactElementVo> elementList = eamArtifactColumnSvc.queryAllColumns(elementDto);
                    for (EamArtifactElementVo elementVo : elementList) {
                        List<String> elements = elementVo.getElements();
                        for (String element : elements) {
                            JSONObject jsonObject = JSONObject.parseObject(element);
                            String type = jsonObject.getString("type");
                            Boolean assetsFlag = jsonObject.getBoolean("assetsFlag");
                            if (!BinaryUtils.isEmpty(type) && type.equals("class") && assetsFlag) {
                                classIds.add(jsonObject.getLong("id"));
                            }
                        }
                    }
                }
            }
            if (!BinaryUtils.isEmpty(cdt.getClassId())) {
                ciCdt.setClassId(cdt.getClassId());
            }
            if (cdt.getIsMore() == 0) {
                pageNum = 1;
                pageSize = 6;
            }
            if (BinaryUtils.isEmpty(pageNum) || pageNum < 1) {
                pageNum = 1;
            }
            ESCISearchBean bean = new ESCISearchBean();
            bean.setWords(Arrays.asList(cdt.getWords()));
            bean.setPageNum(pageNum);
            bean.setPageSize(pageSize);
            bean.setDomainId(domainId);
            if (!classIds.isEmpty()) {
                bean.setClassIds(classIds);
            }

            if (cdt.getLibType() == LibType.PRIVATE) {
                bean.setOwnerCode(cdt.getOwnerCode());
            }
            List<String> queryList = new ArrayList<>();
            queryList.add("attrs.*");
            bean.setSearchKeys(queryList);
            CcCiSearchPage ccCiSearchPage = getCiSvc(cdt.getLibType()).searchCIByBean(bean);

            Map<String, List<CcCiObj>> data = new HashMap<>();
            for (String word : cdt.getWords()) {
                data.put(word, new ArrayList<>());
            }
            VcCiSearchPage ciPage = new VcCiSearchPage(ccCiSearchPage.getPageNum(), ccCiSearchPage.getPageSize(), ccCiSearchPage.getTotalRows(), ccCiSearchPage.getTotalPages(), data);
            ciPage.setClassMp(ccCiSearchPage.getData().getClassMp());

            if (!BinaryUtils.isEmpty(ciPage.getClassMp())) {
                Map<Long, CcCiClassObj> clmap = ciPage.getClassMp();
                Set<Long> clIdSet = clmap.keySet();
            }
            ciSearchPages.add(ciPage);
        }
        return ciSearchPages;
    }

    @Override
    public Map<String, ? extends SaveBatchCIContext> copyCiListByIds(List<ESCIInfo> ciList, String ownerCode, LibType libType, String postfix) {
        if (libType == LibType.BASELINE) {
            return iciApiSvc.copyCiListByIds(ciList, ownerCode);
        } else {
            return getCiSvc(libType).extendCopyCiListByIds(ciList, ownerCode, postfix);
        }
    }

    @Override
    public Map<Long, List<String>> queryEnumDataByClassId(Long classId) {
        CcCiClassInfo ccCiClassInfo = classSvc.queryClassInfoById(classId);
        if (BinaryUtils.isEmpty(ccCiClassInfo)) {
            throw new BinaryException("当前分类不存在");
        }
        Map<Long, List<String>> data = new HashMap<>();
        // 对当前查询数据进行再次封装 将关联属性项与数据字典项的具体值当成枚举值存放在 ENUM_VALUES字段
        for (CcCiAttrDef ccCiAttrDef : ccCiClassInfo.getAttrDefs()) {
            if (ccCiAttrDef.getProType() == DATA_DICT) {
                Long sourceClassId = CiClassProDropSourceDefHelper.getCiClassProDropSourceClassId(ccCiAttrDef.getProDropSourceDef().trim());
                Long[] sourceAttrDefIds = CiClassProDropSourceDefHelper.getCiClassProDropSourceDefIds(ccCiAttrDef.getProDropSourceDef().trim());
                data.put(ccCiAttrDef.getId(), dictSvc.getExteralDictValues(SysUtil.getCurrentUserInfo().getDomainId(), sourceClassId, sourceAttrDefIds));
            }
            if (ccCiAttrDef.getProType() == REL_ATTR) {
                Long sourceDictClassId = CiClassProDropSourceDefHelper.getCiClassProDropSourceClassId(ccCiAttrDef.getProDropSourceDef().trim());
                Long[] sourceDictAttrDefIds = CiClassProDropSourceDefHelper.getCiClassProDropSourceDefIds(ccCiAttrDef.getProDropSourceDef().trim());
                ESAttrAggBean esAttrAggBean = new ESAttrAggBean();
                esAttrAggBean.setClassId(sourceDictClassId);
                esAttrAggBean.setAttrDefIds(sourceDictAttrDefIds);
                esAttrAggBean.setPageSize(1000);
                data.put(ccCiAttrDef.getId(), iciApiSvc.getAttrValuesBySearchBean(esAttrAggBean).getData());
            }
        }
        return data;
    }

    @Override
    public CcCiInfo getPrivateCIInfoByDesginCode(String ciCode) {
        if (BinaryUtils.isEmpty(ciCode)) {
            return null;
        }
        SysUser currentUserInfo = SysUtil.getCurrentUserInfo();
        // 根据设计库 code 去私有库查询对应数据
        CCcCi cdt = new CCcCi();
        cdt.setCiCodeEqual(ciCode);
        cdt.setOwnerCodeEqual(currentUserInfo.getLoginCode());
        List<CcCiInfo> privateCIInfo = iamsCiPrivateSvc.queryCiInfoList(currentUserInfo.getDomainId(), cdt, null, false, true);
        if (!CollectionUtils.isEmpty(privateCIInfo)) {
            return privateCIInfo.get(0);
        }
        // 数据为空 获取设计库业务主键
        cdt.setOwnerCodeEqual(null);
        List<CcCiInfo> desginCIInfo = iamsCiDesignSvc.queryCiInfoList(currentUserInfo.getDomainId(), cdt, null, false, true);
        if (CollectionUtils.isEmpty(desginCIInfo)) {
            return null;
        }
        List<String> primaryKeys = new ArrayList<>();
        desginCIInfo.forEach(e -> {
            primaryKeys.add(e.getCi().getCiPrimaryKey());
        });

        // 私有库根据业务主键查询 info
        ESCISearchBean esciSearchBean = new ESCISearchBean();
        esciSearchBean.setCiPrimaryKeys(primaryKeys);
        esciSearchBean.setOwnerCode(currentUserInfo.getLoginCode());
        Page<ESCIInfo> esciInfoPage = iamsCiPrivateSvc.searchESCIByBean(esciSearchBean);
        if (!CollectionUtils.isEmpty(esciInfoPage.getData())) {
            CCcCi cdt1 = new CCcCi();
            cdt1.setCiCodeEqual(esciInfoPage.getData().get(0).getCiCode());
            List<CcCiInfo> ciInfos = iamsCiPrivateSvc.queryCiInfoList(currentUserInfo.getDomainId(), cdt1, null, false, true);
            return ciInfos.get(0);
        }
        // 根据主键没有查到 在私有库创建
        CcCiInfo creatInfo = desginCIInfo.get(0);
        creatInfo.getCi().setId(null);
        creatInfo.getCi().setOwnerCode(currentUserInfo.getLoginCode());
        creatInfo.getCi().setLocalVersion(0L);
        Long aLong = iamsCiPrivateSvc.saveOrUpdate(creatInfo);
        creatInfo.getCi().setId(aLong);
        return creatInfo;
    }

    @Override
    public Map<String, Long> existDataByClassId(CiQueryCdtExtend cdt) {
        // 根据 classId 分别查询 私有库 设计库 运行库 的CI数量
        if (BinaryUtils.isEmpty(cdt.getClassId())) {
            throw new BinaryException("分类ID不能为空");
        }
        Map<String, Long> result = new HashMap<>();     // 返回值
        SysUser currentUserInfo = SysUtil.getCurrentUserInfo();     // 当前用户信息

        ESCISearchBean esciSearchBean = new ESCISearchBean();
        esciSearchBean.setClassIds(Collections.singletonList(cdt.getClassId()));
        // 运行库分类下的数量
        LibTypeUtil.setLibType("BASELINE");
//        esciSearchBean.setLibType(LibType.BASELINE);
        Long baseLineCINum = iciApiSvc.countByQuery(esciSearchBean);
        result.put("BASELINE", baseLineCINum);
        // 设计库分类下的数量
        LibTypeUtil.setLibType("DESIGN");
        // esciSearchBean.setLibType(LibType.DESIGN);
        Long desginCINum = iamsCiDesignSvc.countByQuery(esciSearchBean);
        result.put("DESGIN", desginCINum);
        // 私有库分类下的数量 条件加上ownerCode
        esciSearchBean.setOwnerCode(currentUserInfo.getLoginCode());
        LibTypeUtil.setLibType("PRIVATE");
//        esciSearchBean.setLibType(LibType.PRIVATE);
        Long privateCINum = iamsCiPrivateSvc.countByQuery(esciSearchBean);
        result.put("PRIVATE", privateCINum);

        return result;
    }

    @Override
    public List<ClassNodeInfo> findClassManagerList(Long classId) {
        if (classId != null && Objects.equals(classId, 0L)) {
            return Collections.emptyList();
        }
        List<ClassNodeInfo> classTree = classSvc.getClassTree();
        if (classId != null && !CollectionUtils.isEmpty(classTree)) {
            List<ClassNodeInfo> newClassTree = classTree;
            classTree = new ArrayList<>();
            for (ClassNodeInfo classNodeInfo : newClassTree) {
                List<ClassNodeInfo> childrenNode = classNodeInfo.getChildren();
                boolean result = false;
                for (ClassNodeInfo classNode : childrenNode) {
                    if (Objects.equals(classNode.getId(), classId)) {
                        List<ClassNodeInfo> newChildrenNode = new ArrayList<>();
                        newChildrenNode.add(classNode);
                        classNodeInfo.setChildren(newChildrenNode);
                        classTree.add(classNodeInfo);
                        result = true;
                        break;
                    }
                }
                if (result) {
                    break;
                }
            }
        }
        ESCIClassSearchBean esciClassSearchBean = new ESCIClassSearchBean();
        List<CcCiClassInfo> ccCiClassInfos = classSvc.queryCiClassInfoListBySearchBean(esciClassSearchBean);
        HashMap<Long, CcCiClassInfo> ccCiClassInfoMap = Maps.newHashMap();
        for (CcCiClassInfo ccCiClassInfo : ccCiClassInfos) {
            ccCiClassInfoMap.put(ccCiClassInfo.getCiClass().getId(), ccCiClassInfo);
        }
        List<ClassNodeInfo> newClassTree = new ArrayList<>();
        if (!CollectionUtils.isEmpty(classTree)) {
            classTree.stream().forEach(classNode -> {
                if (!CollectionUtils.isEmpty(classNode.getChildren())) {
                    classNode.getChildren().forEach(classInfo -> {
                        CcCiClassInfo ccCiClassInfo = ccCiClassInfoMap.get(classInfo.getId());
                        if (ccCiClassInfo != null && !CollectionUtils.isEmpty(ccCiClassInfo.getAttrDefs())) {
                            List<ClassNodeInfo> sonList = new ArrayList<>();
                            ccCiClassInfo.getAttrDefs().forEach(attrItem -> {
                                ClassNodeInfo classNodeInfo = new ClassNodeInfo();
                                classNodeInfo.setId(attrItem.getId());
                                classNodeInfo.setName(attrItem.getProName());
                                StringBuilder stringBuilder = new StringBuilder();
                                stringBuilder.append(classNode.getName()).append("/")
                                        .append(classInfo.getName()).append("/").append(attrItem.getProName());
                                classNodeInfo.setType(stringBuilder.toString());
                                sonList.add(classNodeInfo);
                            });
                            classInfo.setChildren(sonList);
                        }
                    });
                    newClassTree.add(classNode);
                }
            });
        }
        return newClassTree;
    }

    @Override
    public List<DiagramSelectVo> selectClassByArtifact(DiagramSelectParamDto paramDto) {
        String loginCode = SysUtil.getCurrentUserInfo().getLoginCode();
        Long domainId = SysUtil.getCurrentUserInfo().getDomainId();
        if (BinaryUtils.isEmpty(paramDto.getDiagramId()) || BinaryUtils.isEmpty(paramDto.getCiCode())) {
            throw new BinaryException("视图加密id和节点ciCode参数都不能为空");
        }
        /**
         * 先锁定到视图，拿到视图中的制品数据，再拿到制品分栏中的关系数据，
         * 根据节点ciCode，查询出所在分类信息，然后以源端取到对应的目标端分类，再根据每个目标端分类，找到分类下的ci数据---设计库；
         */
        ESDiagramDTO esDiagram = diagramApiClient.queryFullDiagramByIds(Collections.singletonList(paramDto.getDiagramId())).get(0);
        String viewType = esDiagram.getDiagram().getViewType();
        ElementDto elementDto = new ElementDto();
        elementDto.setArtifactId(Long.valueOf(viewType));
        elementDto.setType(3);
        //查询的是制品分栏 架构元素关系栏
        List<EamArtifactElementVo> elementVos = eamArtifactColumnSvc.queryAllColumns(elementDto);
        if (BinaryUtils.isEmpty(elementVos)) {
            return new ArrayList<>();
        }
        List<String> elements = elementVos.stream().map(EamArtifactElementVo::getElements).flatMap(Collection::stream).collect(Collectors.toList());
        /**
         * 根据节点ciCode查询所在分类----源端分类
         * 传过来的是私有库的 源端，拿到分类信息之后，要目标分类的设计库数据；
         */
        CCcCi cdt = new CCcCi();
        cdt.setCiCode(paramDto.getCiCode());
        cdt.setOwnerCodeEqual(loginCode);
        List<CcCiInfo> ccCiInfos = iciSwitchSvc.queryCiInfoList(domainId, cdt, "", false, false, LibType.PRIVATE);
        if (BinaryUtils.isEmpty(ccCiInfos)) {
            return new ArrayList<>();
        }
        //取到源端分类ClassCode
        Long sourceClassId = ccCiInfos.get(0).getCi().getClassId();
        //根据classwId获取classCode;
        ESCIClassInfo sourceClassInfo = ciClassApiSvc.queryClassById(sourceClassId);
        String sourceClassCode = sourceClassInfo.getClassCode();
        /**
         * 将符合条件的目标端收集起来
         * 条件1：目标端classCode= sourceClassCode;
         * 条件2：构建方式为超文本  mode =6;
         */
        List<ESCIClassInfo> targetClass = new ArrayList<>();
        for (String element : elements) {
            CiClassRltVo ciClassRltVo = JSON.parseObject(element, CiClassRltVo.class);
            String classCode = ciClassRltVo.getSourceCiInfo().getClassCode();
            if (sourceClassCode.equals(classCode) && ciClassRltVo.getMode() == 6) {
                targetClass.add(ciClassRltVo.getTargetCiInfo());
            }
        }
        /**
         * 根据收集出来的分类信息，查找对应分类下的设计库的ci数据；
         */
        if (BinaryUtils.isEmpty(targetClass)) {
            return new ArrayList<>();
        }
        Long[] ids = targetClass.stream().map(ESCIClassInfo::getId).distinct().toArray(Long[]::new);
        CCcCi cdtParam = new CCcCi();
        cdtParam.setClassIds(ids);
        //查出所有的目标端分类，要进行分组
        List<ESCIInfo> targetCiInfos = iciSwitchSvc.queryESCIInfoList(domainId, cdtParam, "", false, LibType.DESIGN);
        Map<Long, List<ESCIInfo>> targetMap = targetCiInfos.stream().collect(Collectors.groupingBy(ESCIInfo::getClassId));
        List<DiagramSelectVo> voList = new ArrayList<>();
        //去重
        ArrayList<ESCIClassInfo> collect = targetClass.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(ESCIClassInfo::getId))), ArrayList::new));
        for (ESCIClassInfo classInfo : collect) {
            Long classId = classInfo.getId();
            if (!BinaryUtils.isEmpty(targetMap) && !BinaryUtils.isEmpty(targetMap.get(classId))) {
                List<ESCIInfo> targetCiList = targetMap.get(classId);
                DiagramSelectVo diagramSelectVo = new DiagramSelectVo();
                diagramSelectVo.setCiClass(classInfo);
                diagramSelectVo.setAttrDefs(classInfo.getAttrDefs());
                diagramSelectVo.setCiList(targetCiList);
                voList.add(diagramSelectVo);
            }
        }
        return voList;
    }

    /**
     * 私有库在其他图中创建关系，一个任务被多个角色执行，再拖入到活动图中，也应该加上校验；
     * 根据视图id,获取到 模型树及对应的层级，通过参数两个ciCode,取到对应分类
     * 先跟配置中做个匹配校验，校验上关系了，再查询两者在设计库是否有关系，
     * 若有关系，接口返回true,反之 返回false;
     */
    @Override
    public Boolean judgeLaneDragCi(LaneDragCiDto ciDto) {

        SysUser userInfo = SysUtil.getCurrentUserInfo();
        Long domainId = userInfo.getDomainId();
        String diagramId = ciDto.getDiagramId();
        ESDiagram esDiagram = diagramApiClient.getEsDiagram(diagramId, 0);
        if(BinaryUtils.isEmpty(esDiagram)){
            throw new BinaryException("视图不存在/已被删除");
        }
        String loginCode = esDiagram.getOwnerCode();
        EamCategory category = categorySvc.selectByDiagramId(diagramId, loginCode, LibType.PRIVATE);
        if (BinaryUtils.isEmpty(category)) {
            throw new BinaryException("未获取到当前视图挂载目录");
        }
        EamMultiModelHierarchy model = modelHierarchySvc.getModelById(category.getModelId());
        if (BinaryUtils.isEmpty(model) || model.getDataStatus() == 0) {
            throw new BinaryException("当前模型关联模型工艺已删除,请联系管理员!");
        }
        EamCategory modelRoot = categorySvc.getModelRoot(category.getModelId(), loginCode, LibType.PRIVATE);
        EamHierarchyDto hierarchy = hierarchySvc.queryByLvlAndModelId(category.getDirLvl()-modelRoot.getDirLvl()-1, category.getModelId(), domainId);

        if (!hierarchy.getCheckActive().equals(true)) {
            throw new BinaryException("层级配置中活动图拖拽开关未打开，请联系管理员!");
        }
        List<EamArtifactRltVo> rltList = hierarchy.getRltList();
        EamArtifactRltVo rltVo = null;
        //非泳道布局||无关系数据；
        if (hierarchy.getInheritLayout() != 3 || BinaryUtils.isEmpty(rltList)) {
            return false;
        }
        //非L0层&&有一条关系，不做校验
        if (hierarchy.getDirLvl() != 0 && rltList.size() < 2) {
            return false;
        }
        if (hierarchy.getDirLvl() == 0) {
            rltVo = rltList.get(0);
        } else if (rltList.size() == 2) {//其他层级，有两条关系数据，去第二条关系数据
            rltVo = rltList.get(1);
        }
        if(BinaryUtils.isEmpty(rltVo)){
            return false;
        }
        VcCiClassInfo rltClassInfo = rltVo.getRltClassInfo();
        ESCIClassInfo sourceCiInfo = rltVo.getSourceCiInfo();
        String sourceName = sourceCiInfo.getClassName();
        Long sourceClassId = sourceCiInfo.getId();
        ESCIClassInfo targetCiInfo = rltVo.getTargetCiInfo();
        String targetName = targetCiInfo.getClassName();
        Long targetClassId = targetCiInfo.getId();
        String rltName = rltClassInfo.getCiClass().getClassName();
        // 校验层级制品中的关系，源端，目标端，关系 和 构建方式 是否正确；
        Long artifactId = hierarchy.getArtifactId();
        List<EamArtifactElementVo> elementVos = eamArtifactColumnSvc.queryByArtifactId(artifactId, Collections.singletonList(3));
        if (BinaryUtils.isEmpty(elementVos)) {
            return false;
        }
        List<String> elements = elementVos.stream().map(EamArtifactElementVo::getElements).flatMap(Collection::stream).collect(Collectors.toList());
        List<CiClassRltVo> rltVoList = new ArrayList<>();
        for (String element : elements) {
            //关系映射的那个实体类；
            CiClassRltVo ciClassRltVo = JSON.parseObject(element, CiClassRltVo.class);
            rltVoList.add(ciClassRltVo);
        }
        //根据关系名称分组；
        Map<String, List<CiClassRltVo>> rltMap = rltVoList.stream().collect(Collectors.groupingBy(each -> each.getRltClassInfo().getCiClass().getClassName()));
        List<CiClassRltVo> rltVos = rltMap.get(rltName);
        if (BinaryUtils.isEmpty(rltVos)) {
            return false;
        }
        Map<String, List<CiClassRltVo>> sourceRltMap = rltVos.stream().collect(Collectors.groupingBy(each -> each.getSourceCiInfo().getClassName()));
        List<CiClassRltVo> targetList = sourceRltMap.get(sourceName);
        if (BinaryUtils.isEmpty(targetList)) {
            return false;
        }
        Map<String, CiClassRltVo> targetMap = targetList.stream().collect(Collectors.toMap(each -> each.getTargetCiInfo().getClassName(), each -> each, (k1, k2) -> k1));
        CiClassRltVo ciClassRltVo = targetMap.get(targetName);
        if (BinaryUtils.isEmpty(ciClassRltVo) || ciClassRltVo.getMode() != 4) {
            return false;
        }

        List<String> ciCodes = ciDto.getCiCodes();
        List<ESCIInfo> ccCiInfos = iciSwitchSvc.getCiByCodes(ciCodes, loginCode, LibType.PRIVATE);
        if (BinaryUtils.isEmpty(ccCiInfos)) {
            throw new BinaryException("ci数据不存在，请检查数据");
        }
        //单个泳道ci的主键 集合
        Map<String, Long> ciCodeMap = ccCiInfos.stream().collect(Collectors.toMap(ESCIInfo::getCiCode, CcCi::getClassId, (k1, k2) -> k1));
        //key = 分类id,value = ciInfo
        Map<Long, List<ESCIInfo>> classMap = ccCiInfos.stream().collect(Collectors.groupingBy(CcCi::getClassId));
        List<Long> classIds = ccCiInfos.stream().map(CcCi::getClassId).collect(Collectors.toList());
        if (!classIds.contains(sourceClassId) || !classIds.contains(targetClassId)) {
            return false;
        }
        /**
         * 如果拖动的是任务，那就是如果能查出来多条关系数据，返回true,如果是一条，要判断另一端是否是私有库现有的角色，不是，返回true
         * 如果拖动的是角色，那就看查出来的多条关系数据，是否有跟当前角色分类id匹配不上的数据（表示有对应的任务已经跟别的角色绑定过关系）
         */
        //拖拽的那条ciCode
        Long classId = ciCodeMap.get(ciDto.getCiCode());
        //查询设计库中的饿关系数据；
        ESRltSearchBean bean = new ESRltSearchBean();
        if (classId.equals(targetClassId)) {
            bean.setTargetCiCodes(Collections.singleton(ciDto.getCiCode()));
        } else {
            /**
             * 如果拖动得是源端ci,那么拿到对应的目标端得ci,去查是否有目标端ci绑定了其他源端，若有，则校验不通过，不允许创建关系；
             */
            Set<String> targetCiCode = classMap.get(targetClassId).stream().map(ESCIInfo::getCiCode).collect(Collectors.toSet());
            bean.setTargetCiCodes(targetCiCode);
        }
        bean.setPageNum(1);
        bean.setPageSize(3000);
        bean.setRltClassIds(Collections.singletonList(rltClassInfo.getCiClass().getId()));
        bean.setSourceClassIds(Collections.singletonList(sourceClassId));
        bean.setTargetClassIds(Collections.singletonList(targetClassId));
        Page<ESCIRltInfo> searchRlt = rltSwitchSvc.searchRlt(bean, LibType.DESIGN);
        List<ESCIRltInfo> data = searchRlt.getData();
        //设计库中没有关系；
        if (BinaryUtils.isEmpty(data)) {
            return false;
        }
        if (classId.equals(targetClassId)) {
            //一个泳道内 只有一个角色，故而取get(0)
            ESCIInfo sourceInfo = classMap.get(sourceClassId).get(0);
            List<String> sourceCiCodes = data.stream().map(ESCIRltInfo::getSourceCiCode).collect(Collectors.toList());
            List<ESCIInfo> designSourceCiList = iciSwitchSvc.getCiByCodes(sourceCiCodes, loginCode, LibType.DESIGN);
            //去设计库，根据ciCode查出来，然后取主键，再去私有库查；
            if (!BinaryUtils.isEmpty(designSourceCiList)) {
                List<String> primaryKeyLists = designSourceCiList.stream().map(ESCIInfo::getCiPrimaryKey).collect(Collectors.toList());
                //如果设计库中跟目标端有此关系的源端ci主键，包含当前私有库中源端（设计库和私有库 ci主键能一致吗）
                if (!primaryKeyLists.contains(sourceInfo.getCiPrimaryKey())) {
                    return true;
                }
            }
        }
        if (classId.equals(sourceClassId)) {
            //拖动的是角色，跟任务是一对多的关系，且一个泳道内，只能存在一个角色，
            List<String> sourceCiCodes = data.stream().map(ESCIRltInfo::getSourceCiCode).collect(Collectors.toList());
            //通过主键校验是否是拖拽的ci数据；
            List<ESCIInfo> sourceCiByCodes = iciSwitchSvc.getCiByCodes(sourceCiCodes, loginCode, LibType.DESIGN);
            if (!BinaryUtils.isEmpty(sourceCiByCodes)) {
                Map<String, List<ESCIInfo>> primaryKeyMap = sourceCiByCodes.stream().collect(Collectors.groupingBy(ESCIInfo::getCiPrimaryKey));
                List<ESCIInfo> sourceCiList = classMap.get(sourceClassId);
                for (ESCIInfo info : sourceCiList) {
                    List<ESCIInfo> infoList = primaryKeyMap.get(info.getCiPrimaryKey());
                    //如果 目标端绑定的源端 中 有任意一个 对应的源端不是 泳道中的源端，则不匀速拖拽创建关系；
                    if (BinaryUtils.isEmpty(infoList) || infoList.size() != primaryKeyMap.values().size()) {
                        return true;
                    }
                }
            }
        }
        return false;
    }

    @Override
    public RemoteResult selectRelationDiagramByCi(String ciCode, String diagramId, Integer dirType,LibType libType) {
        /**
         * 查询当前ci 数据是否被 当前 层级目录绑定过，若绑定了，返回绑定的视图信息
         * ci 传参ciCode,查询当前视图所在模型树目录，取出所有目录下的主视图，看 主视图中是否绑定了 当前这个ci
         * 若有，把当前视图信息组装，返回；
         */
        Long modelId = categorySvc.getModelIdByDiagram(diagramId, libType);
        if (BinaryUtils.isEmpty(modelId)) {
            String message = "请在模型中使用文本链接功能";
            return new RemoteResult(true, -1, message, new HashSet<>());
        }
        //查出x-dirType下所有的模型树，留下当前模型树目录；
        List<EamCategory> catalogList = categorySvc.selectByModelId(modelId, LibType.DESIGN, "");
        if (BinaryUtils.isEmpty(catalogList)) {
            return new RemoteResult(true, 0, "", new HashSet<>());
        }
        //根据模型树下主视图绑定的ciCode对目录进行分组；
        Map<String, List<EamCategory>> ciMap = catalogList.stream().collect(Collectors.groupingBy(EamCategory::getCiCode));
        //把当前模型树目录下的每个层级主视图查询出来
        List<String> diagramIdList = catalogList.stream().map(EamCategory::getDiagramId).filter(Objects::nonNull).collect(Collectors.toList());
        if (BinaryUtils.isEmpty(diagramIdList)) {
            return new RemoteResult(true, 0, "", new HashSet<>());
        }
        String[] diagramIds = diagramIdList.toArray(new String[]{});
        List<ESDiagram> diagramList = diagramApiClient.queryDBDiagramInfoByIds(diagramIds);
        //key=视图id,value=视图信息
        Map<String, ESDiagram> diagramIMap = diagramList.stream().collect(Collectors.toMap(ESDiagram::getDEnergy, each -> each, (k1, k2) -> k1));
        Set<DiagramRelationInfo> relationSet = new HashSet<>();
        if (ciMap.containsKey(ciCode)) {
            List<EamCategory> catalogs = ciMap.get(ciCode);
            for (EamCategory catalog : catalogs) {
                ESDiagram diagram = diagramIMap.get(catalog.getDiagramId());
                if (!BinaryUtils.isEmpty(diagram)) {
                    DiagramRelationInfo relationInfo = new DiagramRelationInfo();
                    relationInfo.setName(diagram.getName());
                    relationInfo.setReleaseDiagramId(diagram.getDEnergy());
                    relationSet.add(relationInfo);
                }
            }
        }
        return new RemoteResult(true, 0, "", relationSet);
    }


    /**
     * @return com.uinnova.project.web.diagram.model.base.VcCiSearchPage
     * @Author wang
     * @Description //通过关键词获取ci数据
     * @Date 10:36 2021/6/8
     * @Param [pageNum, pageSize, cdt, word]
     **/
    private VcCiSearchPage getCiDataByWord(Integer pageNum, Integer pageSize, CiQueryCdtExtend cdt, String word) {

        List<Long> classIds = new ArrayList<>();
        CiQueryCdtExtend cdtInfo = new CiQueryCdtExtend();
        cdtInfo.setViewType(cdt.getProductTypeId());
        cdtInfo.setOwnerCode(cdt.getOwnerCode());
        cdtInfo.setCardId(null);
        List<VcCiClassInfoDto> vcCiClassInfoDtos = eamCiSvc.queryCiCountByClass(cdtInfo, cdt.getLibType());
        if (!CollectionUtils.isEmpty(vcCiClassInfoDtos)) {
            classIds = vcCiClassInfoDtos.stream().map(ciClass -> ciClass.getCiClass().getId()).collect(Collectors.toList());
        } else {
            if (BinaryUtils.isEmpty(cdt.getClassId()) && cdt.getProductTypeId() != null) {
                ElementDto elementDto = new ElementDto();
                elementDto.setArtifactId(Long.valueOf(cdt.getProductTypeId()));
                List<EamArtifactElementVo> eamArtifactElementVos = eamArtifactColumnSvc.queryAllColumns(elementDto);
                for (EamArtifactElementVo eamArtifactElementVo : eamArtifactElementVos) {
                    List<String> elements = eamArtifactElementVo.getElements();
                    for (String element : elements) {
                        JSONObject jsonObject = JSONObject.parseObject(element);
                        if (!(jsonObject.get("type") == null) && jsonObject.get("type").equals("class")) {
                            classIds.add(Long.valueOf(jsonObject.get("id").toString()));
                        }
                    }
                }
            }
        }
        if (cdt.getIsMore() == 0) {
            pageNum = 1;
            pageSize = 6;
        }
        if (BinaryUtils.isEmpty(pageNum) || pageNum < 1) {
            pageNum = 1;
        }
        String searchWord = word;
        Pattern CRLF = Pattern.compile("([\\u200b]|[\\u007f-\\u009f]|\\u00ad|[\\u0483-\\u0489]|[\\u0559-\\u055a]|\\u058a|[\\u0591-\\u05bd]|\\u05bf|[\\u05c1-\\u05c2]|[\\u05c4-\\u05c7]|[\\u0606-\\u060a]|[\\u063b-\\u063f]|\\u0674|[\\u06e5-\\u06e6]|\\u070f|[\\u076e-\\u077f]|\\u0a51|\\u0a75|\\u0b44|[\\u0b62-\\u0b63]|[\\u0c62-\\u0c63]|[\\u0ce2-\\u0ce3]|[\\u0d62-\\u0d63]|\\u135f|[\\u2028-\\u202e]|\\u2044|\\u2071|[\\uf701-\\uf70e]|[\\uf710-\\uf71a]|\\ufb1e|[\\ufc5e-\\ufc62]|\\ufeff|\\ufffc)");
        Matcher m = CRLF.matcher(word);
        if (m.find()) {
            searchWord = m.replaceAll("");
        }
        ESCISearchBean bean = new ESCISearchBean();
        bean.setWords(Collections.singletonList(StringUtils.trim(searchWord)));
        List<String> queryList = new ArrayList<>();
        queryList.add("attrs.*");
        bean.setSearchKeys(queryList);
        bean.setPageNum(pageNum);
        bean.setPageSize(pageSize);
        bean.setDomainId(SysUtil.getCurrentUserInfo().getDomainId());
        if (cdt.getLibType() == LibType.PRIVATE) {
            bean.setOwnerCode(cdt.getOwnerCode());
        }
        if (!ArrayUtils.isEmpty(cdt.getClassIds())) {
            bean.setClassIds(Arrays.asList(cdt.getClassIds()));
        }
        if (!classIds.isEmpty()) {
            bean.setClassIds(classIds);
        }
        //根据关键词查出所有的ci信息
        CcCiSearchPage ccCiSearchPage = getCiSvc(cdt.getLibType()).searchCIByBean(bean);
        //封装关键词和ci信息之间的关系
        Map<String, List<CcCiObj>> data = new HashMap<>();
        data.put(word, ccCiSearchPage.getData().getRecords());

        VcCiSearchPage ciPage = new VcCiSearchPage(ccCiSearchPage.getPageNum(), ccCiSearchPage.getPageSize(), ccCiSearchPage.getTotalRows(), ccCiSearchPage.getTotalPages(), data);
        ciPage.setClassMp(ccCiSearchPage.getData().getClassMp());

        return ciPage;
    }


    /**
     * 获取私有库数据是否存在状态
     */
    private Integer checkPrivateExistStatus(List<ESCIInfo> privateCiList, String ownerCode) {
        for (ESCIInfo esciInfo : privateCiList) {
            BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
            queryBuilder.must(QueryBuilders.termQuery("ciCode.keyword", esciInfo.getCiCode()));
            queryBuilder.must(QueryBuilders.termQuery("ownerCode.keyword", ownerCode));
            queryBuilder.must(QueryBuilders.termQuery("classId", esciInfo.getClassId()));
            Page<ESCIInfo> ciInfoPage = iamsCiPrivateSvc.queryCiInfoPage(1, 1, queryBuilder, "version", false);
            List<ESCIInfo> data = ciInfoPage.getData();
            if (CollectionUtils.isEmpty(data)) {
                return 0;
            }
            Map<String, Object> origAttrs = esciInfo.getAttrs();
            Map<String, Object> targAttrs = data.get(0).getAttrs();

            Map<String, String> originalAttrs = EamUtil.coverToAttrs(origAttrs);
            Map<String, String> targetAttrs = EamUtil.coverToAttrs(targAttrs);

            if (originalAttrs.size() != targetAttrs.size()) {
                return 0;
            }
            Iterator<Map.Entry<String, String>> iterator = originalAttrs.entrySet().iterator();
            boolean checkResult = false;
            while (iterator.hasNext()) {
                Map.Entry<String, String> next = iterator.next();
                String targetValue = targetAttrs.get(next.getKey());
                if (!Objects.equals(next.getValue(), targetValue)) {
                    checkResult = true;
                    break;
                }
            }
            if (!checkResult) {
                return 1;
            }
        }
        return 0;
    }

    @Override
    public boolean findNonCompliance(Long classId, LibType libType) {
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.must(QueryBuilders.termQuery("classId", classId));
        List<ESCIInfo> returnVals = new LinkedList<>();
        long diagramCount = 0l;
        BoolQueryBuilder boolQueryDiagram = QueryBuilders.boolQuery();
        if (LibType.DESIGN.equals(libType)) {
            long count = iamsESCIDesignSvc.countByCondition(boolQueryBuilder);
            if (count > 0) {
                //统计出查询指定分类下面的关系数据 通过rltClassId
                Map<String, Page<ESCIInfo>> rltInfoMap = iamsESCIDesignSvc.getScrollByQuery(1, 3000, boolQueryBuilder, "id", true);
                String scrollId = rltInfoMap.keySet().iterator().next();
                if (rltInfoMap.get(scrollId).getData() != null && rltInfoMap.get(scrollId).getData().size() > 0) {
                    returnVals.addAll(rltInfoMap.get(scrollId).getData());
                }
                if (rltInfoMap.get(scrollId).getTotalRows() > 3000) {
                    while (true) {
                        List<ESCIInfo> nextResults = iamsESCIDesignSvc.getListByScroll(scrollId);
                        if (nextResults != null && nextResults.size() > 0) {
                            returnVals.addAll(nextResults);
                        } else {
                            break;
                        }
                    }
                }
                //下面查询所有发布的视图
                boolQueryDiagram.must(QueryBuilders.termQuery("dataStatus", 1));
                boolQueryDiagram.must(QueryBuilders.termQuery("status", 1));
                boolQueryDiagram.must(QueryBuilders.termQuery("isOpen", 1));
                boolQueryDiagram.must(QueryBuilders.termQuery("historyVersionFlag", 1));
                diagramCount = esDiagramDao.countByCondition(boolQueryDiagram);
            }else{
                return true;
            }
        } else if (LibType.PRIVATE.equals(libType)) {
            long count = iamsESCIPrivateSvc.countByCondition(boolQueryBuilder);
            if (count > 0) {
                //统计出查询指定分类下面的关系数据 通过rltClassId
                Map<String, Page<ESCIInfo>> rltInfoMap = iamsESCIPrivateSvc.getScrollByQuery(1, 3000, boolQueryBuilder, "id", true);
                String scrollId = rltInfoMap.keySet().iterator().next();
                if (rltInfoMap.get(scrollId).getData() != null && rltInfoMap.get(scrollId).getData().size() > 0) {
                    returnVals.addAll(rltInfoMap.get(scrollId).getData());
                }
                if (rltInfoMap.get(scrollId).getTotalRows() > 3000) {
                    while (true) {
                        List<ESCIInfo> nextResults = iamsESCIPrivateSvc.getListByScroll(scrollId);
                        if (nextResults != null && nextResults.size() > 0) {
                            returnVals.addAll(nextResults);
                        } else {
                            break;
                        }
                    }
                }
                //下面查询所有没有发布的视图
                boolQueryDiagram.must(QueryBuilders.termQuery("dataStatus", 1));
                boolQueryDiagram.must(QueryBuilders.termQuery("status", 1));
                boolQueryDiagram.must(QueryBuilders.termQuery("isOpen", 0));
                diagramCount = esDiagramDao.countByCondition(boolQueryDiagram);
            }else{
                return true;
            }
        }

        if (diagramCount > 0) {
            //计算需要线程数
            int threadCount = getThreadCount(diagramCount);
            final CountDownLatch countDownLatch = new CountDownLatch(threadCount);
            ConcurrentLinkedQueue<List<String>> allCiCodeQueue = new ConcurrentLinkedQueue<>();
            ExecutorService threadPool = getThreadPool();
            Map<String, Page<ESDiagram>> diagramMap = esDiagramDao.getScrollByQuery(1, 3000, boolQueryDiagram, "id", true);
            String scrollId = diagramMap.keySet().iterator().next();
            if (diagramMap.get(scrollId).getData() != null && diagramMap.get(scrollId).getData().size() > 0) {
                List<ESDiagram> firstDiagramList = diagramMap.get(scrollId).getData();
                //调用线程池执行线程
                threadPool.submit(new CiTask(allCiCodeQueue, returnVals, firstDiagramList, esDiagramNodeDao,countDownLatch));
            }
            if (diagramMap.get(scrollId).getTotalRows() > 3000) {
                while (true) {
                    List<ESDiagram> diagramNextResult = esDiagramDao.getListByScroll(scrollId);
                    if (diagramNextResult != null && diagramNextResult.size() > 0) {
                        //调用线程池执行线程
                        threadPool.submit(new CiTask(allCiCodeQueue, returnVals, diagramNextResult, esDiagramNodeDao,countDownLatch));
                    } else {
                        break;
                    }
                }
            }
            try {
                countDownLatch.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            threadPool.shutdown();
            Set<String> collect = allCiCodeQueue.stream().flatMap(List::stream).distinct().collect(Collectors.toSet());
            returnVals.removeIf(item -> collect.contains(item.getCiCode()));
            BoolQueryBuilder boolQueryNonBuilder = QueryBuilders.boolQuery();
            boolQueryNonBuilder.must(QueryBuilders.termQuery("classId",classId));
            if (LibType.DESIGN.equals(libType)) {
                iamsCIDesignNonComplianceDao.deleteByQuery(boolQueryNonBuilder,true);
                List<List<ESCIInfo>> chunks = new ArrayList<List<ESCIInfo>>();
                for (int i = 0; i < returnVals.size(); i += 3000) {
                    chunks.add(returnVals.subList(i,Math.min(i+3000,returnVals.size())));
                }
                for (List<ESCIInfo> chunk : chunks) {
                    iamsCIDesignNonComplianceDao.saveOrUpdateBatch(chunk);
                }
            }else if (LibType.PRIVATE.equals(libType)) {
                iamsCIPrivateNonComplianceDao.deleteByQuery(boolQueryNonBuilder,true);
                List<List<ESCIInfo>> chunks = new ArrayList<List<ESCIInfo>>();
                for (int i = 0; i < returnVals.size(); i += 3000) {
                    chunks.add(returnVals.subList(i,Math.min(i+3000,returnVals.size())));
                }
                for (List<ESCIInfo> chunk : chunks) {
                    iamsCIPrivateNonComplianceDao.saveOrUpdateBatch(chunk);
                }
            }
        }
        return true;
    }

    private int getThreadCount(long diagramCount) {
        if (diagramCount % 3000l == 0) {
            return (int)diagramCount / 3000;
        }else{
            return (int) (diagramCount/3000l)+1;
        }

    }

    private ExecutorService getThreadPool() {
        // 设置线程池参数
        int corePoolSize = 2;
        int maximumPoolSize = 2;
        int maxQueueSize = 100;
        long keepAliveTime = 0L;
        TimeUnit unit = TimeUnit.MILLISECONDS;
        BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<Runnable>(maxQueueSize);
        ThreadFactory threadFactory = Executors.defaultThreadFactory();
        RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy();

        // 创建线程池
        return new ThreadPoolExecutor(
                corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);
    }

    @Override
    public CiGroupPage queryPageBySearchBeanVO(ESCISearchBeanVO bean, boolean hasClass, LibType libType) {
        if (LibType.BASELINE.equals(libType)) {
            return iciApiSvc.queryPageBySearchBean(bean, hasClass);
        } else if(LibType.DESIGN.equals(libType)){
            return iamsCiDesignSvc.queryPageBySearchBeanVO(bean, hasClass);
        }else{
            return iamsCiPrivateSvc.queryPageBySearchBeanVO(bean,hasClass);
        }
    }
    @Override
    public ResponseEntity<byte[]> exportCiOrClassByConditions(ExportCiVO exportDto, LibType libType) {
        if (LibType.BASELINE.equals(libType)) {
            return iciApiSvc.exportCiOrClass(exportDto);
        } else if(LibType.DESIGN.equals(libType)){
            return iamsCiDesignSvc.exportCiOrClassByConditions(exportDto);
        }else{
            return iamsCiPrivateSvc.exportCiOrClassByConditions(exportDto);
        }
    }

    @Override
    public ResponseEntity<byte[]> exportCiClassAndAttrs(ExportCiVO exportDto, LibType libType) {
        if (LibType.BASELINE.equals(libType)) {
            return iciApiSvc.exportCiOrClass(exportDto);
        } else if(LibType.DESIGN.equals(libType)){
            return iamsCiDesignSvc.exportCiClassAndAttrs(exportDto);
        }else{
            return iamsCiPrivateSvc.exportCiClassAndAttrs(exportDto);
        }
    }

    @Override
    public Map<String, Long> getCiCountMap(Collection<String> classCodes, String ownerCode, LibType libType) {
        if(CollectionUtils.isEmpty(classCodes)){
            return Collections.emptyMap();
        }
        List<CcCiClassInfo> classList = ciClassApiSvc.getByClassCodes(classCodes, SysUtil.getCurrentUserInfo().getDomainId());
        if(CollectionUtils.isEmpty(classList)){
            return Collections.emptyMap();
        }
        List<Long> classIds = classList.stream().map(e -> e.getCiClass().getId()).collect(Collectors.toList());
        ESCISearchBean bean = new ESCISearchBean();
        bean.setClassIds(classIds);
        if(!BinaryUtils.isEmpty(ownerCode) && LibType.PRIVATE.equals(libType)){
            bean.setOwnerCode(ownerCode);
        }
        Map<Long, Long> countMap = this.countCiNumGroupClsByQuery(bean, libType);
        Map<String, Long> result = new HashMap<>();
        for (CcCiClassInfo each : classList) {
            result.put(each.getCiClass().getClassCode(), countMap.getOrDefault(each.getCiClass().getId(), 0L));
        }
        return result;
    }

    @Override
    public CiGroupPage queryReleCiInfo(ESCiReleAssetSearchBean bean, LibType libType) {
        BinaryUtils.checkEmpty(bean.getClassId(), "分类ID");
        ESCISearchBean searchBean = new ESCISearchBean();
        searchBean.setClassIds(Lists.newArrayList(bean.getClassId()));
        if (!BinaryUtils.isEmpty(bean.getBindId())) {
            CcCiClassInfo ccCiClassInfo = esciClassSvc.queryClassInfoById(bean.getClassId());
            Assert.notNull(ccCiClassInfo, "分类不存在");
            Long classId = ccCiClassInfo.getCiClass().getId();
            searchBean.setClassIds(Lists.newArrayList(classId));

            Map<Long, String> attrDefMap = ccCiClassInfo.getAttrDefs().stream().collect(Collectors.toMap(CcCiAttrDef::getId, e -> e.getProName(), (k1, k2) -> k1));
            AssetAttrDataScreen dateScreenInfo = assetAttrDataScreenSvc.getDateScreenInfo(bean.getBindId(), bean.getClassId());
            if (!BinaryUtils.isEmpty(dateScreenInfo) && org.apache.commons.collections4.CollectionUtils.isNotEmpty(dateScreenInfo.getScreenInfo())) {
                List<ClsAttrQueryGroup> orClsAttrQueryGroups = new ArrayList<>();
                for (List<JSONObject> list : dateScreenInfo.getScreenInfo()) {
                    ClsAttrQueryGroup filterGroup = new ClsAttrQueryGroup();
                    List<ESAttrBean> andAttrs = new ArrayList<>();
                    for (JSONObject json : list) {
                        long key = json.getLongValue("key");
                        String ccCiAttrDef = attrDefMap.get(key);
                        if (!BinaryUtils.isEmpty(ccCiAttrDef)) {
                            ESAttrBean esAttrBean = new ESAttrBean();
                            esAttrBean.setKey(ccCiAttrDef);
                            esAttrBean.setValue(json.getString("value"));
                            esAttrBean.setOptType(json.getIntValue("optType"));
                            andAttrs.add(esAttrBean);
                        }
                    }
                    filterGroup.setClassId(classId);
                    if (!org.apache.commons.collections4.CollectionUtils.isEmpty(andAttrs)) {
                        filterGroup.setAndAttrs(andAttrs);
                    }
                    orClsAttrQueryGroups.add(filterGroup);
                }
                searchBean.setOrClsAttrQueryGroups(orClsAttrQueryGroups);
            }
        }
        if (!BinaryUtils.isEmpty(bean.getLike())) {
            searchBean.setWords(Lists.newArrayList(bean.getLike()));
            searchBean.setSearchKeys(Lists.newArrayList("ciPrimaryKey"));
        }
        searchBean.setCiCodes(bean.getCiCodes());
        searchBean.setPageSize(bean.getPageSize());
        searchBean.setPageNum(bean.getPageNum());
        if (libType.equals(LibType.DESIGN)) {
            return iamsCiDesignSvc.queryPageBySearchBean(searchBean, false);
        } else {
            return new CiGroupPage();
        }

    }

    @Override
    public List<CcCiInfo> getCIInfoListByCIPrimaryKeys(Long domainId, List<List<String>> ciPrimaryKeys, LibType libType) {
        if (LibType.BASELINE.equals(libType)) {
            return iciApiSvc.getCIInfoListByCIPrimaryKeys(domainId, ciPrimaryKeys);
        } else if(LibType.DESIGN.equals(libType)){
            return iamsCiDesignSvc.getCIInfoListByCIPrimaryKeys(domainId, ciPrimaryKeys);
        }else{
            return iamsCiPrivateSvc.getCIInfoListByCIPrimaryKeys(domainId, ciPrimaryKeys);
        }
    }
}
